package procsim;

public class Register implements Element{
    protected int bits, val;
    protected MSignal result;
    private MSignal inSig;
    private Signal loadS, clearS;
    protected String name;
    protected static boolean ticking = false;
    public Register(int numOfBits, int init, MSignal in){
        bits=numOfBits;
        val=init;
        inSig=in;
        if(in!=null) in.addElement(this);
        result=new MSignal(numOfBits, init);
        name="REG";
    }
    public Register(int numOfBits, int init, MSignal in, String nam){
        this(numOfBits, init, in);
        name=nam;
    }
    public void clear(){
        val=0x0;
    }
    public void load(){
        val=inSig.get();
    }
    public Register setInSignal(MSignal in){
        if(in!=null) in.addElement(this);
        inSig=in;
        return this;
    }
    public Register setLoadSignal(Signal load){
        if(load!=null) load.addElement(this);
        loadS=load;
        if (clearS!=null) clearS.set(0);
        return this;
    }
    public Register setClearSignal(Signal clear){
        if(clear!=null) clear.addElement(this);
        clearS=clear;
        if (loadS!=null) loadS.set(0);
        return this;
    }
    protected void deactivateLoadClear(){
        if(loadS!=null) loadS.set(0);
        if(clearS!=null) clearS.set(0);
    }
    public Register setResult(MSignal sig){
        result=sig;
        return this;
    }
    @Override
    public Register tick() {
        if(loadS!=null && !loadS.isNull())
            load();
        if(clearS!=null && !clearS.isNull())
            clear();
        if(result!=null) result.set(new MSignal(bits, val, "regval"+val));
        return this;
    }
    @Override
    public MSignal result(){
        return result;
    }
    @Override
    public String toString(){
        return ""+result();
    }
    public int getNumOfBits(){
        return bits;
    }
    public String getName(){
        return name;
    }
    public void setName(String nam){
        name=nam;
    }
    public Register set(int i){
        if(result!=null) result.set(new MSignal(bits, val=i, "regval"+val));
        return this;
    }
    @Override
    public void updateSignal(Sig sig){
        if(ticking) return;
        if(inSig!=null && inSig==sig)
            inSig.set(sig.get(), false);
        if(loadS!=null && loadS==sig)
            loadS.set(sig.get(), false);
        if(clearS!=null && clearS==sig)
            clearS.set(sig.get(), false);
    }
    public static void beginTicking(){
        ticking = true;
    }
    public static void endTicking(){
        ticking = false;
    }
}
